//! 管理字典
use ane_system::dao::{SysDict, SysDictDataDo, SysDictDataVo, SysDictDo, SysDictVo};
use axum::{
    extract::{Path, Query},
    response::IntoResponse,
    routing::get,
    Extension, Router,
};
use common::page::{PageInfo, PageParams};
use loginmanager::AuthUser;

use crate::{auth_manager::LoginUser, extract::ValJson};
use crate::{error::AppResult, extract::Json, state::ShareState};

pub fn get_route<S>() -> Router<S>
where
    S: Sync + Send + Clone + 'static,
{
    Router::<S>::new()
        .route("/", get(list_dict).post(create))
        .route("/data/", get(list_dict).post(create))
}

pub async fn list_dict(
    Extension(state): Extension<ShareState>,
    Query(page_params): Query<PageParams>,
) -> AppResult<impl IntoResponse> {
    SysDict::list_type::<SysDictVo>(state.db(), page_params.zero_page(), page_params.page_size)
        .await
        .map(|(total, datas)| PageInfo::new(datas, &page_params, total))
        .map(Json)
        .map_err(Into::into)
}

pub async fn create(
    Extension(state): Extension<ShareState>,
    AuthUser(user): AuthUser<LoginUser>,
    ValJson(data): ValJson<SysDictDo>,
) -> AppResult<impl IntoResponse> {
    SysDict::create_type(state.db(), data, user.id)
        .await
        .map(Json)
        .map_err(Into::into)
}

pub async fn update(
    Extension(state): Extension<ShareState>,
    Path(id): Path<i32>,
    AuthUser(user): AuthUser<LoginUser>,
    ValJson(data): ValJson<SysDictDo>,
) -> AppResult<impl IntoResponse> {
    SysDict::update_type(state.db(), id, data, user.id)
        .await
        .map(Json)
        .map_err(Into::into)
}

pub async fn delete(
    Extension(state): Extension<ShareState>,
    Path(id): Path<i32>,
) -> AppResult<impl IntoResponse> {
    SysDict::delete_type(state.db(), id)
        .await
        .map(Json)
        .map_err(Into::into)
}

pub async fn list_dict_data(
    Extension(state): Extension<ShareState>,
    Path(dict_type): Path<String>,
    Query(page_params): Query<PageParams>,
) -> AppResult<impl IntoResponse> {
    SysDict::list_dict_data::<SysDictDataVo>(
        state.db(),
        page_params.zero_page(),
        page_params.page_size,
        dict_type,
        None,
    )
    .await
    .map(|(total, datas)| PageInfo::new(datas, &page_params, total))
    .map(Json)
    .map_err(Into::into)
}

pub async fn create_dict_data(
    Extension(state): Extension<ShareState>,
    Path(dict_type): Path<String>,
    AuthUser(user): AuthUser<LoginUser>,
    ValJson(data): ValJson<SysDictDataDo>,
) -> AppResult<impl IntoResponse> {
    SysDict::create_dict_data::<SysDictDataVo>(state.db(), data, user.id)
        .await
        .map(Json)
        .map_err(Into::into)
}

pub async fn update_dict_data(
    Extension(state): Extension<ShareState>,
    Path((dict_type, id)): Path<(String, i32)>,
    AuthUser(user): AuthUser<LoginUser>,
    ValJson(data): ValJson<SysDictDataDo>,
) -> AppResult<impl IntoResponse> {
    SysDict::update_dict_data::<SysDictDataVo>(state.db(), id, data, user.id)
        .await
        .map(Json)
        .map_err(Into::into)
}

pub async fn delete_dict_data(
    Extension(state): Extension<ShareState>,
    Path((dict_type, id)): Path<(String, i32)>,
) -> AppResult<impl IntoResponse> {
    SysDict::delete_dict_data(state.db(), id)
        .await
        .map(Json)
        .map_err(Into::into)
}
